﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Issues.MerchantNeedsHelpWithOutlawsIssueQuestBehavior
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using Helpers;
using System;
using System.Collections.Generic;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.Conversation;
using TaleWorlds.CampaignSystem.MapEvents;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.ObjectSystem;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Issues
{
  public class MerchantNeedsHelpWithOutlawsIssueQuestBehavior : CampaignBehaviorBase
  {
    private const IssueBase.IssueFrequency MerchantNeedsHelpWithOutlawsIssueFrequency = IssueBase.IssueFrequency.VeryCommon;
    private const int ValidBanditPartyDistance = 40;
    private const int NeededHideoutDistanceToSpawnTheQuest = 50;

    public override void RegisterEvents()
    {
      CampaignEvents.OnCheckForIssueEvent.AddNonSerializedListener((object) this, new Action<Hero>(this.OnCheckForIssue));
    }

    public override void SyncData(IDataStore dataStore)
    {
    }

    private bool ConditionsHold(Hero issueGiver, out Hideout hideout)
    {
      hideout = (Hideout) null;
      if (issueGiver.IsMerchant || issueGiver.IsRuralNotable)
      {
        Settlement nearestHideout = SettlementHelper.FindNearestHideout((Func<Settlement, bool>) (x => x.Hideout.IsInfested && !Campaign.Current.BusyHideouts.Contains(x)));
        if (nearestHideout != null)
        {
          float distance;
          Campaign.Current.Models.MapDistanceModel.GetDistance(issueGiver.GetMapPoint(), nearestHideout, 100f, out distance);
          if ((double) distance < 50.0)
          {
            hideout = nearestHideout.Hideout;
            return true;
          }
        }
      }
      return false;
    }

    public void OnCheckForIssue(Hero hero)
    {
      Hideout hideout;
      if (this.ConditionsHold(hero, out hideout))
        Campaign.Current.IssueManager.AddPotentialIssueData(hero, new PotentialIssueData(new PotentialIssueData.StartIssueDelegate(this.OnSelected), typeof (MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssue), IssueBase.IssueFrequency.VeryCommon, (object) hideout));
      else
        Campaign.Current.IssueManager.AddPotentialIssueData(hero, new PotentialIssueData(typeof (MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssue), IssueBase.IssueFrequency.VeryCommon));
    }

    private IssueBase OnSelected(in PotentialIssueData pid, Hero issueOwner)
    {
      Hideout relatedObject = pid.RelatedObject as Hideout;
      return (IssueBase) new MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssue(issueOwner, relatedObject);
    }

    public class MerchantNeedsHelpWithOutlawsIssue : IssueBase
    {
      private const int IssueDuration = 15;
      private const int QuestTimeLimit = 20;
      private const int MinimumRequiredMenCount = 5;
      private const int AlternativeSolutionMinimumSkillValue = 120;
      private const int AlternativeSolutionTroopTierRequirement = 2;
      [SaveableField(10)]
      private Hideout RelatedHideout;

      internal static void AutoGeneratedStaticCollectObjectsMerchantNeedsHelpWithOutlawsIssue(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this.RelatedHideout);
      }

      internal static object AutoGeneratedGetMemberValueRelatedHideout(object o)
      {
        return (object) ((MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssue) o).RelatedHideout;
      }

      public override IssueBase.AlternativeSolutionScaleFlag AlternativeSolutionScaleFlags
      {
        get
        {
          return IssueBase.AlternativeSolutionScaleFlag.Casualties | IssueBase.AlternativeSolutionScaleFlag.FailureRisk;
        }
      }

      private int TotalPartyCount => (int) (2.0 + 6.0 * (double) this.IssueDifficultyMultiplier);

      public override int AlternativeSolutionBaseNeededMenCount
      {
        get => 8 + MathF.Ceiling(11f * this.IssueDifficultyMultiplier);
      }

      protected override int AlternativeSolutionBaseDurationInDaysInternal
      {
        get => 5 + MathF.Ceiling(7f * this.IssueDifficultyMultiplier);
      }

      protected override int RewardGold
      {
        get => (int) (400.0 + 1500.0 * (double) this.IssueDifficultyMultiplier);
      }

      public override TextObject IssueBriefByIssueGiver
      {
        get
        {
          return new TextObject("{=ib6ltlM0}Yes... We've always had trouble with bandits, but recently we've had a lot more than our share. The hills outside of town are infested. A lot of us are afraid to take their goods to market. Some have been murdered. People tell me, 'I'm getting so desperate, maybe I'll turn bandit myself.' It's bad...[ib:demure2][if:convo_dismayed]");
        }
      }

      public override TextObject IssueAcceptByPlayer
      {
        get => new TextObject("{=qNxdWLFY}So you want me to hunt them down?");
      }

      public override TextObject IssueQuestSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject parent = new TextObject("{=DlRMT7XD}Well, {?PLAYER.GENDER}my lady{?}sir{\\?}, you'll never get all those outlaws,[if:convo_thinking] but if word gets around that you took down some of the most vicious ones - let's say {TOTAL_COUNT} bands of brigands - robbing us wouldn't seem so lucrative. Maybe the rest would go bother someone else... Do you think you can help us?");
          StringHelpers.SetCharacterProperties("PLAYER", CharacterObject.PlayerCharacter, parent);
          parent.SetTextVariable("TOTAL_COUNT", this.TotalPartyCount);
          return parent;
        }
      }

      public override TextObject IssueAlternativeSolutionExplanationByIssueGiver
      {
        get
        {
          TextObject explanationByIssueGiver = new TextObject("{=5RjvnQ3d}I bet even a party of {ALTERNATIVE_COUNT} properly trained men accompanied by one of your lieutenants can handle any band they find. Give them {TOTAL_DAYS} days, say... That will make a difference.[if:convo_undecided_open]");
          explanationByIssueGiver.SetTextVariable("ALTERNATIVE_COUNT", this.GetTotalAlternativeSolutionNeededMenCount());
          explanationByIssueGiver.SetTextVariable("TOTAL_DAYS", this.GetTotalAlternativeSolutionDurationInDays());
          return explanationByIssueGiver;
        }
      }

      public override TextObject IssuePlayerResponseAfterAlternativeExplanation
      {
        get
        {
          return new TextObject("{=BPfuSkCl}That depends. How many men do you think are required to get the job done?");
        }
      }

      public override TextObject IssueQuestSolutionAcceptByPlayer
      {
        get
        {
          TextObject solutionAcceptByPlayer = new TextObject("{=2ApU6iCB}I'll hunt down {TOTAL_COUNT} bands of brigands for you.");
          solutionAcceptByPlayer.SetTextVariable("TOTAL_COUNT", this.TotalPartyCount);
          return solutionAcceptByPlayer;
        }
      }

      public override TextObject IssueAlternativeSolutionAcceptByPlayer
      {
        get
        {
          TextObject solutionAcceptByPlayer = new TextObject("{=DLbFbYkR}I will have one of my companions and {ALTERNATIVE_COUNT} of my men patrol the area for {TOTAL_DAYS} days.");
          solutionAcceptByPlayer.SetTextVariable("ALTERNATIVE_COUNT", this.GetTotalAlternativeSolutionNeededMenCount());
          solutionAcceptByPlayer.SetTextVariable("TOTAL_DAYS", this.GetTotalAlternativeSolutionDurationInDays());
          return solutionAcceptByPlayer;
        }
      }

      public override TextObject IssueDiscussAlternativeSolution
      {
        get
        {
          return new TextObject("{=PexmGuOd}{?PLAYER.GENDER}Madam{?}Sir{\\?}, I am happy to tell that the men you left are patrolling, and already we feel safer. Thank you again.[ib:demure][if:convo_grateful]");
        }
      }

      public override TextObject IssueAlternativeSolutionResponseByIssueGiver
      {
        get
        {
          TextObject parent = new TextObject("{=FYfZFve3}Thank you, {?PLAYER.GENDER}my lady{?}my lord{\\?}. Hopefully, we can travel safely again.");
          StringHelpers.SetCharacterProperties("PLAYER", CharacterObject.PlayerCharacter, parent);
          return parent;
        }
      }

      public override bool IsThereAlternativeSolution => true;

      public override bool IsThereLordSolution => false;

      protected override int CompanionSkillRewardXP
      {
        get => (int) (600.0 + 800.0 * (double) this.IssueDifficultyMultiplier);
      }

      protected override TextObject AlternativeSolutionStartLog
      {
        get
        {
          TextObject parent = new TextObject("{=Bdt41knf}You have accepted {QUEST_GIVER.LINK}'s request to find at least {TOTAL_COUNT} different parties of brigands around {QUEST_SETTLEMENT} and sent {COMPANION.LINK} and with {?COMPANION.GENDER}her{?}his{\\?} {ALTERNATIVE_COUNT} of your men to deal with them. They should return with the reward of {GOLD_AMOUNT}{GOLD_ICON} denars as promised by {QUEST_GIVER.LINK} after dealing with them in {RETURN_DAYS} days.");
          parent.SetTextVariable("TOTAL_COUNT", this.TotalPartyCount);
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.IssueOwner.CharacterObject, parent);
          StringHelpers.SetCharacterProperties("COMPANION", this.AlternativeSolutionHero.CharacterObject, parent);
          parent.SetTextVariable("QUEST_SETTLEMENT", this.IssueOwner.CurrentSettlement.EncyclopediaLinkWithName);
          parent.SetTextVariable("ALTERNATIVE_COUNT", this.AlternativeSolutionSentTroops.TotalManCount - 1);
          parent.SetTextVariable("GOLD_AMOUNT", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          parent.SetTextVariable("RETURN_DAYS", this.GetTotalAlternativeSolutionDurationInDays());
          return parent;
        }
      }

      public override TextObject Title
      {
        get
        {
          TextObject parent = new TextObject("{=ABmCO23x}{QUEST_GIVER.NAME} Needs Help With Brigands");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.IssueOwner.CharacterObject, parent);
          return parent;
        }
      }

      public override TextObject Description
      {
        get
        {
          return new TextObject("{=sAobCa9U}Brigands are disturbing travelers outside the town. Someone needs to hunt them down.");
        }
      }

      public MerchantNeedsHelpWithOutlawsIssue(Hero issueOwner, Hideout relatedHideout)
        : base(issueOwner, CampaignTime.DaysFromNow(15f))
      {
        this.RelatedHideout = relatedHideout;
        Campaign.Current.BusyHideouts.Add(relatedHideout.Settlement);
      }

      protected override float GetIssueEffectAmountInternal(IssueEffect issueEffect)
      {
        if (issueEffect == DefaultIssueEffects.SettlementProsperity)
          return -0.2f;
        if (issueEffect == DefaultIssueEffects.IssueOwnerPower)
          return -0.1f;
        return issueEffect == DefaultIssueEffects.SettlementSecurity ? -1f : 0.0f;
      }

      public override (SkillObject, int) GetAlternativeSolutionSkill(Hero hero)
      {
        return (hero.GetSkillValue(DefaultSkills.Tactics) >= hero.GetSkillValue(DefaultSkills.Scouting) ? DefaultSkills.Tactics : DefaultSkills.Scouting, 120);
      }

      public override bool DoTroopsSatisfyAlternativeSolution(
        TroopRoster troopRoster,
        out TextObject explanation)
      {
        explanation = TextObject.Empty;
        return QuestHelper.CheckRosterForAlternativeSolution(troopRoster, this.GetTotalAlternativeSolutionNeededMenCount(), ref explanation, 2);
      }

      public override bool AlternativeSolutionCondition(out TextObject explanation)
      {
        explanation = TextObject.Empty;
        return QuestHelper.CheckRosterForAlternativeSolution(MobileParty.MainParty.MemberRoster, this.GetTotalAlternativeSolutionNeededMenCount(), ref explanation, 2);
      }

      public override bool IsTroopTypeNeededByAlternativeSolution(CharacterObject character)
      {
        return character.Tier >= 2;
      }

      protected override void AlternativeSolutionEndWithSuccessConsequence()
      {
        this.RelationshipChangeWithIssueOwner = 3;
        if (this.IssueOwner.CurrentSettlement.IsVillage && this.IssueOwner.CurrentSettlement.Village.TradeBound != null)
        {
          this.IssueOwner.CurrentSettlement.Village.Bound.Town.Security += 5f;
          this.IssueOwner.CurrentSettlement.Village.Bound.Town.Prosperity += 5f;
        }
        else if (this.IssueOwner.CurrentSettlement.IsTown)
        {
          this.IssueOwner.CurrentSettlement.Town.Security += 5f;
          this.IssueOwner.CurrentSettlement.Town.Prosperity += 5f;
        }
        Hero.MainHero.Clan.AddRenown(1f);
      }

      protected override void AlternativeSolutionEndWithFailureConsequence()
      {
        if (this.IssueOwner.CurrentSettlement.IsVillage)
          this.IssueOwner.CurrentSettlement.Village.Bound.Town.Prosperity -= 10f;
        else if (this.IssueOwner.CurrentSettlement.IsTown)
          this.IssueOwner.CurrentSettlement.Town.Prosperity -= 10f;
        this.RelationshipChangeWithIssueOwner = -5;
      }

      public override IssueBase.IssueFrequency GetFrequency()
      {
        return IssueBase.IssueFrequency.VeryCommon;
      }

      protected override bool CanPlayerTakeQuestConditions(
        Hero issueGiver,
        out IssueBase.PreconditionFlags flag,
        out Hero relationHero,
        out SkillObject skill)
      {
        flag = IssueBase.PreconditionFlags.None;
        relationHero = (Hero) null;
        skill = (SkillObject) null;
        if ((double) issueGiver.GetRelationWithPlayer() < -10.0)
        {
          flag |= IssueBase.PreconditionFlags.Relation;
          relationHero = issueGiver;
        }
        if (MobileParty.MainParty.MemberRoster.TotalHealthyCount < 5)
          flag |= IssueBase.PreconditionFlags.NotEnoughTroops;
        if (issueGiver.MapFaction.IsAtWarWith(Hero.MainHero.MapFaction))
          flag |= IssueBase.PreconditionFlags.AtWar;
        return flag == IssueBase.PreconditionFlags.None;
      }

      public override bool IssueStayAliveConditions()
      {
        return !this.IssueOwner.CurrentSettlement.IsRaided && !this.IssueOwner.CurrentSettlement.IsUnderRaid && this.RelatedHideout != null && this.RelatedHideout.IsInfested;
      }

      protected override void OnGameLoad()
      {
        if (this.RelatedHideout == null)
        {
          this.CompleteIssueWithCancel();
        }
        else
        {
          if (!MBSaveLoad.IsUpdatingGameVersion || !(MBSaveLoad.LastLoadedGameVersion < ApplicationVersion.FromString("v1.2.9")) || Campaign.Current.BusyHideouts.Contains(this.RelatedHideout.Settlement))
            return;
          Campaign.Current.BusyHideouts.Add(this.RelatedHideout.Settlement);
        }
      }

      protected override void HourlyTick()
      {
      }

      protected override QuestBase GenerateIssueQuest(string questId)
      {
        return (QuestBase) new MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssueQuest(questId, this.IssueOwner, CampaignTime.DaysFromNow(20f), this.RewardGold, this.TotalPartyCount, this.RelatedHideout);
      }

      protected override void CompleteIssueWithTimedOutConsequences()
      {
      }

      protected override void OnIssueFinalized()
      {
        if (this.RelatedHideout == null)
          return;
        Campaign.Current.BusyHideouts.Remove(this.RelatedHideout.Settlement);
      }
    }

    public class MerchantNeedsHelpWithOutlawsIssueQuest : QuestBase
    {
      [SaveableField(10)]
      private readonly int _totalPartyCount;
      [SaveableField(30)]
      private int _destroyedPartyCount;
      [SaveableField(50)]
      private int _recruitedPartyCount;
      [SaveableField(40)]
      private List<MobileParty> _validPartiesList;
      [SaveableField(70)]
      private Hideout _relatedHideout;
      [SaveableField(60)]
      private JournalLog _questProgressLogTest;

      internal static void AutoGeneratedStaticCollectObjectsMerchantNeedsHelpWithOutlawsIssueQuest(
        object o,
        List<object> collectedObjects)
      {
        ((MBObjectBase) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
        collectedObjects.Add((object) this._validPartiesList);
        collectedObjects.Add((object) this._relatedHideout);
        collectedObjects.Add((object) this._questProgressLogTest);
      }

      internal static object AutoGeneratedGetMemberValue_totalPartyCount(object o)
      {
        return (object) ((MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssueQuest) o)._totalPartyCount;
      }

      internal static object AutoGeneratedGetMemberValue_destroyedPartyCount(object o)
      {
        return (object) ((MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssueQuest) o)._destroyedPartyCount;
      }

      internal static object AutoGeneratedGetMemberValue_recruitedPartyCount(object o)
      {
        return (object) ((MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssueQuest) o)._recruitedPartyCount;
      }

      internal static object AutoGeneratedGetMemberValue_validPartiesList(object o)
      {
        return (object) ((MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssueQuest) o)._validPartiesList;
      }

      internal static object AutoGeneratedGetMemberValue_relatedHideout(object o)
      {
        return (object) ((MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssueQuest) o)._relatedHideout;
      }

      internal static object AutoGeneratedGetMemberValue_questProgressLogTest(object o)
      {
        return (object) ((MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssueQuest) o)._questProgressLogTest;
      }

      public override TextObject Title
      {
        get
        {
          TextObject parent = new TextObject("{=PBGiIbEM}{ISSUE_GIVER.NAME} Needs Help With Brigands");
          StringHelpers.SetCharacterProperties("ISSUE_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      public override bool IsRemainingTimeHidden => false;

      private int _questPartyProgress => this._destroyedPartyCount + this._recruitedPartyCount;

      private TextObject _playerStartsQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=6iLxrDBa}You have accepted {QUEST_GIVER.LINK}'s request to find at least {TOTAL_COUNT} different parties of brigands around {QUEST_SETTLEMENT} and decided to hunt them down personally. {?QUEST_GIVER.GENDER}She{?}He{\\?} will reward you {AMOUNT}{GOLD_ICON} gold once you have dealt with them.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("TOTAL_COUNT", this._totalPartyCount);
          parent.SetTextVariable("QUEST_SETTLEMENT", this.QuestGiver.CurrentSettlement.EncyclopediaLinkWithName);
          parent.SetTextVariable("AMOUNT", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject _successQuestLogText1
      {
        get
        {
          TextObject parent = new TextObject("{=cQ6CzXKM}You have defeated all the brigands as {QUEST_GIVER.LINK} has asked. {?QUEST_GIVER.GENDER}She{?}He{\\?} is grateful. And sends you the reward, {GOLD_AMOUNT}{GOLD_ICON} gold as promised.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("SETTLEMENT", this.QuestGiver.CurrentSettlement.Name);
          parent.SetTextVariable("GOLD_AMOUNT", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject _successQuestLogText2
      {
        get
        {
          TextObject parent = new TextObject("{=dSHgU9gD}You have defeated some of the brigands and recruited the rest into your party. {QUEST_GIVER.LINK} is grateful and sends you the {GOLD_AMOUNT}{GOLD_ICON} as promised. ");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("GOLD_AMOUNT", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject _successQuestLogText3
      {
        get
        {
          TextObject parent = new TextObject("{=3V5udYJO}You have recruited the brigands into your party. {QUEST_GIVER.LINK} finds your solution acceptable and sends you the {GOLD_AMOUNT}{GOLD_ICON} as promised.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("GOLD_AMOUNT", this.RewardGold);
          parent.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
          return parent;
        }
      }

      private TextObject _timeoutLog
      {
        get
        {
          TextObject parent = new TextObject("{=Tcux6Sru}You have failed to defeat all {TOTAL_COUNT} outlaw parties in time as {QUEST_GIVER.LINK} asked. {?QUEST_GIVER.GENDER}She{?}He{\\?} is very disappointed.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("TOTAL_COUNT", this._totalPartyCount);
          return parent;
        }
      }

      private TextObject _questGiverVillageRaided
      {
        get
        {
          TextObject parent = new TextObject("{=4rCIZ6e5}{QUEST_SETTLEMENT} was raided, Your agreement with {QUEST_GIVER.LINK} is canceled.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          parent.SetTextVariable("QUEST_SETTLEMENT", this.QuestGiver.CurrentSettlement.EncyclopediaLinkWithName);
          return parent;
        }
      }

      private TextObject _questCanceledWarDeclaredLog
      {
        get
        {
          TextObject parent = new TextObject("{=vW6kBki9}Your clan is now at war with {QUEST_GIVER.LINK}'s realm. Your agreement with {QUEST_GIVER.LINK} is canceled.");
          StringHelpers.SetCharacterProperties("QUEST_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      private TextObject _playerDeclaredWarQuestLogText
      {
        get
        {
          TextObject parent = new TextObject("{=DDur6mHb}Your actions have started a war with {ISSUE_GIVER.LINK}'s faction. Your agreement with {ISSUE_GIVER.LINK} is failed.");
          StringHelpers.SetCharacterProperties("ISSUE_GIVER", this.QuestGiver.CharacterObject, parent);
          return parent;
        }
      }

      public MerchantNeedsHelpWithOutlawsIssueQuest(
        string questId,
        Hero giverHero,
        CampaignTime duration,
        int rewardGold,
        int totalPartyCount,
        Hideout relatedHideout)
        : base(questId, giverHero, duration, rewardGold)
      {
        this._totalPartyCount = totalPartyCount;
        this._destroyedPartyCount = 0;
        this._recruitedPartyCount = 0;
        this._validPartiesList = new List<MobileParty>();
        this._relatedHideout = relatedHideout;
        Campaign.Current.BusyHideouts.Add(relatedHideout.Settlement);
        this.AddHideoutPartiesToValidPartiesList();
        this.SetDialogs();
        this.InitializeQuestOnCreation();
      }

      protected override void SetDialogs()
      {
        TextObject npcText = new TextObject("{=PQIYPCDn}Very good. I will be waiting for the good news then. Once you return, I'm ready to offer a reward of {REWARD_GOLD}{GOLD_ICON} denars. Just make sure that you defeat at least {TROOP_COUNT} bands no more than a day's ride away from here.[ib:normal][if:convo_bemused]");
        npcText.SetTextVariable("REWARD_GOLD", this.RewardGold);
        npcText.SetTextVariable("TROOP_COUNT", this._totalPartyCount);
        npcText.SetTextVariable("GOLD_ICON", "{=!}<img src=\"General\\Icons\\Coin@2x\" extend=\"8\">");
        this.OfferDialogFlow = DialogFlow.CreateDialogFlow("issue_classic_quest_start").NpcLine(npcText).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).Consequence(new ConversationSentence.OnConsequenceDelegate(this.QuestAcceptedConsequences)).CloseDialog();
        this.DiscussDialogFlow = DialogFlow.CreateDialogFlow("quest_discuss").NpcLine(new TextObject("{=jjTcNhKE}Have you been able to find any bandits yet?[if:convo_undecided_open]")).Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).BeginPlayerOptions().PlayerOption(new TextObject("{=mU45Th70}We're off to hunt them now.")).NpcLine(new TextObject("{=u9vtceCV}You are a savior.[if:convo_astonished]")).CloseDialog().Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).PlayerOption(new TextObject("{=QPv1b7f8}I haven't had the time yet.")).NpcLine(new TextObject("{=6ba4n9n6}We are waiting for your good news {?PLAYER.GENDER}my lady{?}sir{\\?}.[if:convo_focused_happy]")).CloseDialog().Condition((ConversationSentence.OnConditionDelegate) (() => Hero.OneToOneConversationHero == this.QuestGiver)).EndPlayerOptions().CloseDialog();
      }

      private void QuestAcceptedConsequences()
      {
        this.StartQuest();
        this._questProgressLogTest = this.AddDiscreteLog(this._playerStartsQuestLogText, new TextObject("{=HzcLsnYn}Destroyed parties"), this._destroyedPartyCount, this._totalPartyCount, hideInformation: true);
      }

      private void AddQuestStepLog()
      {
        this._questProgressLogTest.UpdateCurrentProgress(this._questPartyProgress);
        if (this._questPartyProgress >= this._totalPartyCount)
        {
          this.SuccessConsequences();
        }
        else
        {
          TextObject message = new TextObject("{=xbVCRbUu}You hunted {CURRENT_COUNT}/{TOTAL_COUNT} gang of brigands.");
          message.SetTextVariable("CURRENT_COUNT", this._questPartyProgress);
          message.SetTextVariable("TOTAL_COUNT", this._totalPartyCount);
          MBInformationManager.AddQuickInformation(message);
        }
      }

      protected override void HourlyTick()
      {
      }

      protected override void RegisterEvents()
      {
        CampaignEvents.OnSessionLaunchedEvent.AddNonSerializedListener((object) this, new Action<CampaignGameStarter>(this.OnSessionLaunched));
        CampaignEvents.HourlyTickPartyEvent.AddNonSerializedListener((object) this, new Action<MobileParty>(this.HourlyTickParty));
        CampaignEvents.MobilePartyDestroyed.AddNonSerializedListener((object) this, new Action<MobileParty, PartyBase>(this.MobilePartyDestroyed));
        CampaignEvents.WarDeclared.AddNonSerializedListener((object) this, new Action<IFaction, IFaction, DeclareWarAction.DeclareWarDetail>(this.OnWarDeclared));
        CampaignEvents.OnClanChangedKingdomEvent.AddNonSerializedListener((object) this, new Action<Clan, Kingdom, Kingdom, ChangeKingdomAction.ChangeKingdomActionDetail, bool>(this.OnClanChangedKingdom));
        CampaignEvents.VillageBeingRaided.AddNonSerializedListener((object) this, new Action<Village>(this.OnVillageRaided));
        CampaignEvents.MapEventStarted.AddNonSerializedListener((object) this, new Action<MapEvent, PartyBase, PartyBase>(this.OnMapEventStarted));
        CampaignEvents.BanditPartyRecruited.AddNonSerializedListener((object) this, new Action<MobileParty>(this.OnBanditPartyRecruited));
        CampaignEvents.SettlementEntered.AddNonSerializedListener((object) this, new Action<MobileParty, Settlement, Hero>(this.OnSettlementEntered));
        CampaignEvents.OnSettlementLeftEvent.AddNonSerializedListener((object) this, new Action<MobileParty, Settlement>(this.OnSettlementLeft));
        CampaignEvents.OnGameLoadFinishedEvent.AddNonSerializedListener((object) this, new Action(this.OnGameLoadFinished));
      }

      private void OnSessionLaunched(CampaignGameStarter campaignGameStarter)
      {
        if (!MBSaveLoad.IsUpdatingGameVersion || !(MBSaveLoad.LastLoadedGameVersion < ApplicationVersion.FromString("v1.2.9")))
          return;
        if (!Campaign.Current.BusyHideouts.Contains(this._relatedHideout.Settlement))
        {
          Campaign.Current.BusyHideouts.Add(this._relatedHideout.Settlement);
        }
        else
        {
          this.CompleteQuestWithCancel();
          Campaign.Current.BusyHideouts.Add(this._relatedHideout.Settlement);
        }
      }

      private void OnGameLoadFinished()
      {
        if (this._relatedHideout != null)
          return;
        Settlement nearestHideout = SettlementHelper.FindNearestHideout((Func<Settlement, bool>) (x => x.Hideout.IsInfested));
        if (nearestHideout != null)
        {
          float distance;
          Campaign.Current.Models.MapDistanceModel.GetDistance(this.QuestGiver.CurrentSettlement, nearestHideout, 100f, out distance);
          if ((double) distance < 50.0)
            this._relatedHideout = nearestHideout.Hideout;
        }
        if (this._relatedHideout != null)
          this.AddHideoutPartiesToValidPartiesList();
        else
          this.CompleteQuestWithCancel();
      }

      private void AddHideoutPartiesToValidPartiesList()
      {
        foreach (MobileParty party in (List<MobileParty>) this._relatedHideout.Settlement.Parties)
        {
          if (party.IsBandit)
            this._validPartiesList.Add(party);
        }
      }

      private void OnSettlementLeft(MobileParty party, Settlement settlement)
      {
        if (!this._validPartiesList.Contains(party) || !settlement.IsHideout || settlement.Hideout != this._relatedHideout)
          return;
        this._validPartiesList.Remove(party);
      }

      private void OnSettlementEntered(MobileParty party, Settlement settlement, Hero hero)
      {
        if (party == null || !party.IsBandit || !settlement.IsHideout || settlement.Hideout != this._relatedHideout)
          return;
        this._validPartiesList.Add(party);
      }

      private void OnBanditPartyRecruited(MobileParty banditParty)
      {
        if (!this._validPartiesList.Contains(banditParty))
          return;
        ++this._recruitedPartyCount;
        this._validPartiesList.Remove(banditParty);
        this.AddQuestStepLog();
      }

      private void OnMapEventStarted(
        MapEvent mapEvent,
        PartyBase attackerParty,
        PartyBase defenderParty)
      {
        if (!QuestHelper.CheckMinorMajorCoercion((QuestBase) this, mapEvent, attackerParty))
          return;
        QuestHelper.ApplyGenericMinorMajorCoercionConsequences((QuestBase) this, mapEvent);
      }

      private void OnVillageRaided(Village village)
      {
        if (village != this.QuestGiver.CurrentSettlement.Village)
          return;
        this.AddLog(this._questGiverVillageRaided);
        this.CompleteQuestWithCancel();
      }

      private void OnClanChangedKingdom(
        Clan clan,
        Kingdom oldKingdom,
        Kingdom newKingdom,
        ChangeKingdomAction.ChangeKingdomActionDetail detail,
        bool showNotification = true)
      {
        if (!this.QuestGiver.CurrentSettlement.MapFaction.IsAtWarWith(Hero.MainHero.MapFaction))
          return;
        this.CompleteQuestWithCancel(this._questCanceledWarDeclaredLog);
      }

      private void OnWarDeclared(
        IFaction faction1,
        IFaction faction2,
        DeclareWarAction.DeclareWarDetail detail)
      {
        QuestHelper.CheckWarDeclarationAndFailOrCancelTheQuest((QuestBase) this, faction1, faction2, detail, this._playerDeclaredWarQuestLogText, this._questCanceledWarDeclaredLog);
      }

      private void MobilePartyDestroyed(MobileParty mobileParty, PartyBase destroyerParty)
      {
        if (destroyerParty != PartyBase.MainParty || !this._validPartiesList.Contains(mobileParty))
          return;
        ++this._destroyedPartyCount;
        this.AddQuestStepLog();
      }

      private void HourlyTickParty(MobileParty mobileParty)
      {
        if (!this.IsOngoing || !mobileParty.IsBandit || mobileParty.MapEvent != null || !mobileParty.MapFaction.IsBanditFaction || mobileParty.IsCurrentlyUsedByAQuest)
          return;
        if ((double) mobileParty.Position2D.DistanceSquared(this.QuestGiver.CurrentSettlement.Position2D) <= 1600.0)
        {
          if (!this._validPartiesList.Contains(mobileParty))
          {
            if (!this.IsTracked((ITrackableCampaignObject) mobileParty))
              this.AddTrackedObject((ITrackableCampaignObject) mobileParty);
            this._validPartiesList.Add(mobileParty);
            if (mobileParty.CurrentSettlement != null || (double) MBRandom.RandomFloat >= 1.0 / (double) this._validPartiesList.Count)
              return;
            SetPartyAiAction.GetActionForPatrollingAroundSettlement(mobileParty, this.QuestGiver.CurrentSettlement);
            mobileParty.Ai.SetDoNotMakeNewDecisions(true);
            mobileParty.IgnoreForHours(500f);
          }
          else
          {
            if ((double) MBRandom.RandomFloat >= 0.20000000298023224)
              return;
            mobileParty.Ai.SetDoNotMakeNewDecisions(false);
          }
        }
        else
        {
          if (!this.IsTracked((ITrackableCampaignObject) mobileParty))
            return;
          this.RemoveTrackedObject((ITrackableCampaignObject) mobileParty);
          this._validPartiesList.Remove(mobileParty);
          mobileParty.Ai.SetDoNotMakeNewDecisions(false);
        }
      }

      private void SuccessConsequences()
      {
        if (this._destroyedPartyCount == this._totalPartyCount)
          this.AddLog(this._successQuestLogText1);
        else if (this._recruitedPartyCount != 0 && this._recruitedPartyCount < this._totalPartyCount)
          this.AddLog(this._successQuestLogText2);
        else
          this.AddLog(this._successQuestLogText3);
        this.RelationshipChangeWithQuestGiver = 3;
        GiveGoldAction.ApplyBetweenCharacters((Hero) null, Hero.MainHero, this.RewardGold);
        if (this.QuestGiver.CurrentSettlement.IsVillage && this.QuestGiver.CurrentSettlement.Village.TradeBound != null)
        {
          this.QuestGiver.CurrentSettlement.Village.Bound.Town.Security += 5f;
          this.QuestGiver.CurrentSettlement.Village.Bound.Town.Prosperity += 5f;
        }
        else if (this.QuestGiver.CurrentSettlement.IsTown)
        {
          this.QuestGiver.CurrentSettlement.Town.Security += 5f;
          this.QuestGiver.CurrentSettlement.Town.Prosperity += 5f;
        }
        Hero.MainHero.Clan.AddRenown(1f);
        this.CompleteQuestWithSuccess();
      }

      protected override void OnTimedOut()
      {
        this.RelationshipChangeWithQuestGiver = -5;
        if (this.QuestGiver.CurrentSettlement.IsVillage)
          this.QuestGiver.CurrentSettlement.Village.Bound.Town.Prosperity -= 10f;
        else if (this.QuestGiver.CurrentSettlement.IsTown)
          this.QuestGiver.CurrentSettlement.Town.Prosperity -= 10f;
        this.AddLog(this._timeoutLog);
      }

      protected override void InitializeQuestOnGameLoad() => this.SetDialogs();

      protected override void OnFinalize()
      {
        foreach (MobileParty validParties in this._validPartiesList)
        {
          validParties.Ai.SetDoNotMakeNewDecisions(false);
          validParties.IgnoreForHours(0.0f);
          if (this.IsTracked((ITrackableCampaignObject) validParties))
            this.RemoveTrackedObject((ITrackableCampaignObject) validParties);
        }
        this._validPartiesList.Clear();
        Campaign.Current.BusyHideouts.Remove(this._relatedHideout.Settlement);
      }
    }

    public class MerchantNeedsHelpWithOutlawsIssueTypeDefiner : SaveableTypeDefiner
    {
      public MerchantNeedsHelpWithOutlawsIssueTypeDefiner()
        : base(590000)
      {
      }

      protected override void DefineClassTypes()
      {
        this.AddClassDefinition(typeof (MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssue), 1);
        this.AddClassDefinition(typeof (MerchantNeedsHelpWithOutlawsIssueQuestBehavior.MerchantNeedsHelpWithOutlawsIssueQuest), 2);
      }
    }
  }
}
